﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Purdue.Extensions
{
    public static class EnumerableExtensions
    {

        public static int IndexOf<T>(this IEnumerable<T> items, T item)
        {
            var list = items as IList;
            if (list != null)
            {
                return list.IndexOf(item);
            }

            return items.FindIndex(i => i.Equals(item));
        }

        public static int FindIndex<T>(this IEnumerable<T> list, Predicate<T> match)
        {
            if (list == null)
            {
                throw new ArgumentNullException("list");
            }

            if (match == null)
            {
                throw new ArgumentNullException("match");
            }

            int index = 0;
            foreach (var item in list)
            {
                if (match(item))
                {
                    return index;
                }
                index++;
            }
            return -1;
        }

        /// <summary>
        /// list all elements to check if they are equal in the order with another list.
        /// </summary>
        public static bool EqualAll<T>(this IEnumerable<T> first, IEnumerable<T> second, Func<object, object, bool> equals)
        {
            if (equals == null)
                throw new ArgumentNullException("equals");

            if (first == null)
            {
                return (second == null);
            }

            if (second == null)
            {
                return false;
            }

            using (IEnumerator<T> e1 = first.GetEnumerator())
            {
                using (IEnumerator<T> e2 = second.GetEnumerator())
                {
                    while (e1.MoveNext())
                    {
                        if (!e2.MoveNext())
                            return false;

                        if (!equals(e1.Current, e2.Current))
                            return false;
                    }

                    if (e2.MoveNext())
                        return false;
                }
            }
            return true;
        }

        /// <summary>
        /// list all elements to check if they are equal in the order with another list.
        /// </summary>
        public static bool EqualAll<T>(this IEnumerable<T> first, IEnumerable<T> second)
        {
            return first.EqualAll(second, object.Equals);
        }
    }
}
